#include "mytcpsocket.h"
#include "operatedb.h"

MyTcpSocket::MyTcpSocket()
{
    m_pmh = new MsgHandler;
    connect(this, &QTcpSocket::readyRead, this, &MyTcpSocket::recvMsg);
    connect(this, &QTcpSocket::disconnected, this, &MyTcpSocket::clientOffLine);
}

MyTcpSocket::~MyTcpSocket()
{
    delete m_pmh;
}

PDU* MyTcpSocket::handlePDU(PDU *pdu)
{
    qDebug() <<"\n\n\nrecvMsg 消息类型：" <<pdu->uiMsgType
             <<"消息内容：" <<pdu->caMsg
             <<"参数内容：" <<pdu->caData;
    switch (pdu->uiMsgType) {
    case ENUM_MSG_TYPE_REGIST_REQUEST:
        return m_pmh->handleRegist(pdu);
    case ENUM_MSG_TYPE_LOGIN_REQUEST:
        return m_pmh->handleLogin(pdu, m_strName);
    case ENUM_MSG_TYPE_FIND_USER_REQUEST:
        return m_pmh->handleFindUser(pdu);
    case ENUM_MSG_TYPE_ONLINE_USER_REQUEST:
        return m_pmh->handleOnlineUser();
    case ENUM_MSG_TYPE_ADD_FRIEND_REQUEST:
        return m_pmh->handleAddFriend(pdu);
    case ENUM_MSG_TYPE_ADD_FRIEND_AGREE_REQUEST:
        return m_pmh->handleAddFriendAgree(pdu);
    case ENUM_MSG_TYPE_ONLINE_FRIEND_REQUEST:
        return m_pmh->handleOnlineFriend(pdu);
    case ENUM_MSG_TYPE_DEL_FRIEND_REQUEST:
        return m_pmh->handleDelFriend(pdu);
    case ENUM_MSG_TYPE_CHAT_REQUEST:
        m_pmh->handleChat(pdu);
        return NULL;
    case ENUM_MSG_TYPE_MKDIR_REQUEST:
        return m_pmh->handleMKDIR(pdu);
    case ENUM_MSG_TYPE_FLUSH_FILE_REQUEST:
        return m_pmh->handleFlushFile(pdu);
    case ENUM_MSG_TYPE_DEL_DIR_REQUEST:
        return m_pmh->handleDelDir(pdu);
    case ENUM_MSG_TYPE_RENAME_FILE_REQUEST:
        return m_pmh->handleRenameFile(pdu);
    case ENUM_MSG_TYPE_DEL_FILE_REQUEST:
        return m_pmh->handleDelFile(pdu);
    case ENUM_MSG_TYPE_MOVE_FILE_REQUEST:
        return m_pmh->handleMoveFile(pdu);
    case ENUM_MSG_TYPE_UPLOAD_FILE_REQUEST:
        return m_pmh->handleUploadFile(pdu);
    case ENUM_MSG_TYPE_UPLOAD_FILE_DATA_REQUEST:
        return m_pmh->handleUploadFileData(pdu);
    case ENUM_MSG_TYPE_DOWNLOAD_FILE_REQUEST:
        return m_pmh->handleDownloadFile(pdu);
    case ENUM_MSG_TYPE_DOWNLOAD_FILE_DATA_REQUEST:
        return m_pmh->handleDownloadFileData(this);//this就是socket
    case ENUM_MSG_TYPE_SHARE_FILE_REQUEST:
        return m_pmh->handleShareFile(pdu);
    case ENUM_MSG_TYPE_SHARE_FILE_AGREE_REQUEST:
        return m_pmh->handleShareFileAgree(pdu);
    default:
        break;
    }
    return NULL;
}

void MyTcpSocket::writePDU(PDU *respdu)
{
    if(respdu == NULL)//判空
    {
        return;
    }
    write((char*)respdu, respdu->uiPDULen);
    free(respdu);
    respdu = NULL;
}

void MyTcpSocket::recvMsg()
{//函数封装原则：单一职责
    qDebug() << "recvMsg 接收消息长度" << this->bytesAvailable();
    QByteArray data = this->readAll();
    buffer.append(data);
    while(buffer.size() >= int(sizeof(PDU))){//判断是否有一个完整的PDU结构体
        PDU* pdu = (PDU*)buffer.data();//转换为pdu类型的指针
        if(buffer.size() < int(pdu->uiPDULen)){//总的pdu协议长度和buffer比较
            qDebug()<<"buffer.size() < int(pdu->uiPDULen) buffer.size(): " <<buffer.size();
            break;//不够一个包
        }
        PDU* respdu = handlePDU(pdu);//处理
        writePDU(respdu);//发送
        buffer.remove(0,pdu->uiPDULen);//buffer清除处理完的pdu
    }
}

void MyTcpSocket::clientOffLine()
{
    OperateDb::getInstance().handleOffLine(m_strName.toStdString().c_str());
    emit OffLine(this);
}
